package com.tianji.learning.task;

import cn.hutool.core.util.ObjectUtil;
import com.tianji.common.utils.DateUtils;
import com.tianji.learning.domain.po.PointsBoard;
import com.tianji.learning.service.IPointsBoardSeasonService;
import com.tianji.learning.service.IPointsBoardService;
import com.tianji.learning.utils.TableInfoContext;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;

import static com.tianji.learning.constans.SignRecordConstans.POINTS_BOARD_KEY_PRIFIX;

@Slf4j
@Component
@RequiredArgsConstructor
public class XxljobHisBoardData {
    private final IPointsBoardSeasonService seasonService;
    private final IPointsBoardService boardService;
    private final StringRedisTemplate redisTemplate;

    /**
     * 创建历史榜单表
     */
    @XxlJob("createTableJob")
    public void createTable() {
        //1.获取上个月的时间
        LocalDateTime beforMonth = LocalDateTime.now().minusMonths(1);
        //2.根据时间查询上个月的赛季id(调用sevice)
        Integer seasonId = seasonService.querySeasonIdByBeforMonth(beforMonth);
        //3.拼接表名
        String boardName = "points_board_" + seasonId;
        //5.存在则结束，不存在则创建
        boardService.createTbale(boardName);
    }


    /**
     * 将历史赛季排名持久化到数据空中
     */
    @XxlJob("savePointsBoard2DB")
    public void savePointsBoard2DB() {
        //1.获取上个赛季的时间
        LocalDateTime beforTime = LocalDateTime.now().minusMonths(1);
        //1.1根据上个月时间获取赛季id
        Integer seassonId = seasonService.querySeasonIdByBeforMonth(beforTime);
        //1.2获取动态表名
        String tableName = "points_board_" + seassonId;
        //1.3将表明添加至本地线程中
        TableInfoContext.setTableName(tableName);
        //2.查询redis中的上赛季数据
        //2.1组装key
        String key = POINTS_BOARD_KEY_PRIFIX + beforTime.format(DateUtils.DATE_SUFFIX_FORMATTER);
        int index = XxlJobHelper.getShardIndex();  //每台机器的下标索引（索引从0开始）
        int total = XxlJobHelper.getShardTotal();  //机器的数量
        //2.2查询redis中的数据,调用之前
        int pageNo = index + 1, pageSize = 5;  //两台机器，第一台查第一页五条，第二台第二页五条，第一台第三页五条....（可以分工合作）
        while (true) {
            List<PointsBoard> pointsBoards = boardService.pointBoard(key, pageNo, pageSize);
            //3.判断是否存在
            if (ObjectUtil.isEmpty(pointsBoards)) {
                //3.1不存在直接结束
                break;
            }
            //3.2存在则更新到数据库中
            //3.3遍历查询出的历史榜单信息
            for (PointsBoard pointsBoard : pointsBoards) {
                //3.4分装数据
                pointsBoard.setId(pointsBoard.getRank().longValue());
                pointsBoard.setRank(null);
            }
            //3.5批量插入
            boardService.saveBatch(pointsBoards);
            pageNo = pageNo + total;//让第一台机器持久化奇数的页码
        }
        //4.使用完之后，移除表信息，防止内存泄漏
        TableInfoContext.removeTableName();
    }

    /**
     * 持久化之后，删除redis中的历史排行榜数据
     */
    @XxlJob("clearPointsBoardFromRedis")
    public void clearPointsBoardFromRedis() throws InterruptedException {
        //Thread.sleep(10000L);
        //1.组装key
        String key = POINTS_BOARD_KEY_PRIFIX +
                LocalDateTime.now().minusMonths(1).format(DateUtils.DATE_SUFFIX_FORMATTER);
        //2.使用redis的unlike方法异步非阻塞删除
        redisTemplate.unlink(key);
    }

}
